<template>

  <div class='containers'>
<!--    <el-button size='small' type='primary' @click='showUploadDialog'>上传</el-button>-->
    <div class='canvas' ref='canvas'></div>

<!--    <el-dialog title="上传文件" :visible.sync="uploadDialogVisible">-->
<!--      <el-upload-->
<!--        action="#"-->
<!--        :before-upload="handleFileUpload"-->
<!--        :show-file-list="false">-->
<!--        <el-button type="primary">选择文件</el-button>-->
<!--      </el-upload>-->
<!--      <span slot="footer" class="dialog-footer">-->
<!--        <el-button @click="uploadDialogVisible = false">取消</el-button>-->
<!--      </span>-->
<!--    </el-dialog>-->
  </div>
</template>

<script>
// 引入相关的依赖
import BpmnModeler from 'bpmn-js/lib/Modeler'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import customTranslate from './js/customTranslate' // 汉化包引入
import { videoBusiness } from './js/videoBusiness' // 流程图初始配置，编辑的话只需要相同格式的文件替换即可
import { publicSafety } from './js/publicSafety' // 流程图初始配置，编辑的话只需要相同格式的文件替换即可
import { scientificComputing } from './js/scientificComputing'
import {reportingProcess} from "./js";
import xml2js from "xml2js"; // 流程图初始配置，编辑的话只需要相同格式的文件替换即可

export default {
  data() {
    return {
      checkSuccess:true,
      uploadDialogVisible: false,
      bpmnModeler: null,
      canvas: null
    }
  },

  mounted() {
    this.init()
    this.setZoomLevel(1.0) // 设置缩放级别为1.0
    this.autoFit() // 自适应显示流程图
  },

  computed: {},

  methods: {
    showUploadDialog() {
      this.uploadDialogVisible = true;
    },
    handleFileUpload(file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        const xmlStrWithValues = e.target.result;
        this.$refs.modal.import(xmlStrWithValues);
        this.uploadDialogVisible = false;
      };
      reader.readAsText(file);
      return false; // Prevent default upload behavior
    },
    setZoomLevel(level) {
      const canvas = this.bpmnModeler.get('canvas')
      canvas.zoom(level)
    },
    autoFit() {
      const canvas = this.bpmnModeler.get('canvas')
      canvas.zoom('fit-viewport')
    },
    init() {
      // 将汉化包包装成一个模块
      // eslint-disable-next-line no-unused-vars
      const customTranslateMolude = {
        translate: ['value', customTranslate]
      }
      this.bpmnModeler = new BpmnModeler({
        // 建模
        container: this.$refs.canvas,
        propertiesPanel: {
          // 添加控制板
          parent: '#properties-panel'
        },
        // additionalModules: [
        //   // 右边的属性栏
        //   propertiesProviderModule,
        //   propertiesPanelModule,
        //   customTranslateMolude // 汉化模块
        // ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      })
      // this.createNewDiagram('', '', '', '', '', '', '', '', '', '')
    },
    createNewDiagram(vi_1, vi_2, vi_3, vi_4, vi_5, vi_6, vi_7, vi_8, vi_9, vi_10, vi_11, vi_12, vi_13, vi_14, vi_15) {
      // 将字符串转换成图显示出来
      const xmlStrWithValues = videoBusiness.replace('$vi_01$', vi_1)
        .replace('$vi_02$', vi_2).replace('$vi_03$', vi_3).replace('$vi_04$', vi_4)
        .replace('$vi_05$', vi_5).replace('$vi_06$', vi_6).replace('$vi_07$', vi_7)
        .replace('$vi_08$', vi_8).replace('$vi_09$', vi_9).replace('$vi_10$', vi_10)
        .replace('$vi_11$', vi_11).replace('$vi_12$', vi_12).replace('$vi_13$', vi_13)
        .replace('$vi_14$', vi_14).replace('$vi_15$', vi_15)
      this.import(xmlStrWithValues)
      return xmlStrWithValues
    },
    createNewDiagram2(fat_0, fat_1, fat_2, fat_3, fat_4, fat_5, fat_6, fat_7, fat_8, fat_9
      , fat_10, fat_11, fat_12, fat_13, fat_14, fat_15, fat_16, fat_17) {
      // 将字符串转换成图显示出来
      const xmlStrWithValues = publicSafety.replace('$fat_0$', fat_0).replace('$fat_1$', fat_1)
        .replace('$fat_2$', fat_2).replace('$fat_3$', fat_3).replace('$fat_4$', fat_4)
        .replace('$fat_5$', fat_5).replace('$fat_6$', fat_6).replace('$fat_7$', fat_7)
        .replace('$fat_8$', fat_8).replace('$fat_9$', fat_9).replace('$fat_10$', fat_10)
        .replace('$fat_11$', fat_11).replace('$fat_12$', fat_12).replace('$fat_13$', fat_13)
        .replace('$fat_14$', fat_14).replace('$fat_15$', fat_15).replace('$fat_16$', fat_16)
        .replace('$fat_17$', fat_17)
      this.import(xmlStrWithValues)
      return xmlStrWithValues
    },
    createNewDiagram3(sc_1, sc_2, sc_3, sc_4, sc_5, sc_6, sc_7, sc_8, sc_9, sc_10, sc_11, sc_12, sc_13, sc_14, sc_15, sc_16, sc_17, sc_18, sc_19, sc_20, sc_21, sc_22, sc_23, sc_24, sc_25, sc_26, sc_27, sc_28, sc_29, sc_30, sc_31, sc_32, sc_33, sc_34) {
      // 将字符串转换成图显示出来
      const xmlStrWithValues = scientificComputing.replace('$sc_01$', sc_1)
        .replace('$sc_02$', sc_2).replace('$sc_03$', sc_3).replace('$sc_04$', sc_4)
        .replace('$sc_05$', sc_5).replace('$sc_06$', sc_6).replace('$sc_07$', sc_7)
        .replace('$sc_08$', sc_8).replace('$sc_09$', sc_9).replace('$sc_10$', sc_10)
        .replace('$sc_11$', sc_11).replace('$sc_12$', sc_12).replace('$sc_13$', sc_13)
        .replace('$sc_14$', sc_14).replace('$sc_15$', sc_15).replace('$sc_16$', sc_16)
        .replace('$sc_17$', sc_17).replace('$sc_18$', sc_18).replace('$sc_19$', sc_19)
        .replace('$sc_20$', sc_20).replace('$sc_21$', sc_21).replace('$sc_22$', sc_22)
        .replace('$sc_23$', sc_23).replace('$sc_24$', sc_24).replace('$sc_25$', sc_25)
        .replace('$sc_26$', sc_26).replace('$sc_27$', sc_27).replace('$sc_28$', sc_28)
        .replace('$sc_29$', sc_29).replace('$sc_30$', sc_30).replace('$sc_31$', sc_31)
        .replace('$sc_32$', sc_32).replace('$sc_33$', sc_33).replace('$sc_34$', sc_34)
      this.import(xmlStrWithValues)
      return xmlStrWithValues
    },
    // 自定义流程图
    createNewDiagram4(xmlStrWithCustom,sc_1, sc_2, sc_3, sc_4, sc_5, sc_6, sc_7, sc_8, sc_9, sc_10, sc_11, sc_12, sc_13, sc_14, sc_15, sc_16, sc_17, sc_18, sc_19, sc_20, sc_21, sc_22, sc_23, sc_24, sc_25, sc_26, sc_27, sc_28, sc_29, sc_30, sc_31, sc_32, sc_33, sc_34) {
      // 将字符串转换成图显示出来

      console.log(xmlStrWithCustom)
      this.parseBpmnXml(xmlStrWithCustom)
      this.importNew(xmlStrWithCustom)

      return xmlStrWithCustom
    },
    async import(xmlStrWithValues) {
      this.bpmnModeler.importXML(xmlStrWithValues, (err) => {
        console.log(111, err)
        if (!err) {
          this.success()
          this.hidePalette() // 调用隐藏左侧栏的方法
        } else {
          this.$message.error('导入XML文件时发生错误,请上传符合BPMN规范的XML文件')
        return;
        }
      })
    },
    async importNew(xmlStrWithValues) {
      this.bpmnModeler.importXML(xmlStrWithValues, (err) => {
        console.log(111, err)
        if (!err) {
          this.success()
          this.hidePalette() // 调用隐藏左侧栏的方法
          // reportingProcess(this.params).then((data) => {
          //   this.flag = true
          //   this.$message({ type: 'success', message: '操作成功' })
          //   this.isLoading = false
          // }).catch((error) => {
          //   console.log(error)
          //   this.isLoading = false
          // })
        } else {
          this.$message.error('导入XML文件时发生错误,请上传符合BPMN规范的XML文件')
          return;
        }
      })
    },
    getCustomCpuValue(xmlStr){
      const doc = new DOMParser().parseFromString(xmlStr, 'application/xml');
      const definitions = doc.getElementsByTagName('definitions')[0];
      const customAttribute = definitions.getAttribute('custom:cpu')
      return customAttribute;
    },
    parseBpmnXml(xmlStr){
      this.bpmnModeler.importXML(xmlStr, (err) => {
        if (err) {
          console.error('导入XML文件时发生错误:', err);
          return;
        }

        const elementRegistry = this.bpmnModeler.get('elementRegistry');
        const taskElements = elementRegistry.filter(element => element.type === 'bpmn:Task');

        const taskAttributes = taskElements.map(task => {
          const businessObject = task.businessObject;
          return {
            name: businessObject.name,
            customAttribute: businessObject.$attrs.number,
            customAttribute2: businessObject.$attrs.customCpu
          };
        });

        const cpuData = []
        const le = []
        // cpuData.push(le)
        const cp = []

        const oo  ={};
        taskAttributes.forEach(task => {
          le.push(parseInt(task.customAttribute))// 第几个
          cp.push(parseInt(task.customAttribute2)) // 具体的值
          oo[task.customAttribute] = task.name;
          console.log(`任务节点名称: ${task.name}, Custom Attribute: ${task.customAttribute} , Custom Attribute2: ${task.customAttribute2}`);
        });
        const paramsRe = {};
        paramsRe.processMap = oo;
        paramsRe.processInfo = xmlStr;
        cpuData.push(le)
        cpuData.push(cp)
        paramsRe.cpuJson = cpuData
        const sequenceFlowElements = elementRegistry.filter(element => element.type === 'bpmn:SequenceFlow');





        // const taskNames = taskElements.map(task => task.businessObject.name);
        // const sequenceFlowNames = sequenceFlowElements.map(flow => flow.businessObject.name);
        const sequenceFlowAttributes = sequenceFlowElements.map(flow => {
          const businessObject = flow.businessObject;
          return {
            name: businessObject.name,
            customAttribute: businessObject.$attrs.customAttribute
          };
        });
        const pplinkData = []
        // const info0 = [0, 1, parseInt(this.process.process_one.task.vi_1)]

        for (const x of sequenceFlowAttributes) {
          if(!x.customAttribute){
            this.$message.error('导入XML文件时发生错误,连线缺少customAttribute')
            return;;
          }
          let split = x.customAttribute.split("_");
          if(!split[0] || !split[1]){
            this.$message.error('导入XML文件时发生错误,customAttribute 没有按照_分割')
            return;;
          }
          const info0 = [parseInt(split[0]), parseInt(split[1]),parseInt(x.name)]
          pplinkData.push(info0)
        }
        paramsRe.reportJson = pplinkData
        console.log("线和线的值",sequenceFlowAttributes);

        // console.log('任务节点名称:', taskNames);
        // console.log('线的名称:', sequenceFlowNames);
        //

        const parser = new xml2js.Parser();

        // cpu 内存
        parser.parseString(xmlStr, (err, result) => {
          if (err) {
            console.error('Error parsing BPMN XML:', err);
            return;
          }

          const definitions = result['bpmn2:definitions'];
          const customAttributes = definitions['$'];
          const cpuValue = customAttributes['custom:cpu'];
          const memValue = customAttributes['custom:mem'];
          const storageValue = customAttributes['custom:storage'];

          if (cpuValue) {
            paramsRe.cpu = cpuValue;
            console.log('CPU Value:', cpuValue);
          } else {
            this.$message.error('导入XML文件时发生错误,CPU为空')
            return;
          }
          // 同理
          if (memValue) {
            paramsRe.mem = memValue;
            console.log('mem Value:', memValue);
          } else {
            this.$message.error('导入XML文件时发生错误,MEM为空')
            return;
          }
          if (storageValue) {
            paramsRe.storage = storageValue;
            console.log('storage Value:', storageValue);
          } else {
            this.$message.error('导入XML文件时发生错误,STORAGE为空')
            return;
          }
        });

        reportingProcess(paramsRe).then((data) => {
          this.flag = true
          this.$message({ type: 'success', message: '操作成功' })
          this.isLoading = false
        }).catch((error) => {
          console.log(error)
          this.isLoading = false
        })
        // const cpuValue = this.getCustomCpuValue(xmlStr);

        // console.log('CPU Value:', cpuValue);
      });

      //

      //

    },
    hidePalette() {
      const paletteContainer = this.$el.querySelector('.djs-palette')
      paletteContainer.style.display = 'none'
    },
    success() {
      console.log('创建成功!')
      this.bpmnModeler.on('commandStack.changed', () => {
        this.getXML().then((xml) => {
        })
      })
      this.addModelerListener()
      this.addEventBusListener()
    },
    getXML() {
      return new Promise((resolve, reject) => {
        this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
          err ? reject(err) : resolve(xml)
        })
      })
    },
    // 添加绑定事件
    addBpmnListener() {
      const that = this
      // 获取a标签dom节点
      const downloadLink = this.$refs.saveDiagram
      const downloadSvgLink = this.$refs.saveSvg
      // 给图绑定事件，当图有发生改变就会触发这个事件
      this.bpmnModeler.on('commandStack.changed', function() {
        that.saveSVG(function(err, svg) {
          that.setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg)
        })
        that.saveDiagram(function(err, xml) {
          that.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml)
        })
      })
    },
    addModelerListener() {
      // 监听 modeler
      const bpmnjs = this.bpmnModeler
      const that = this
      // 'shape.removed', 'connect.end', 'connect.move'
      const events = ['shape.added', 'shape.move.end', 'shape.removed']
      events.forEach(function(event) {
        that.bpmnModeler.on(event, e => {
          var elementRegistry = bpmnjs.get('elementRegistry')
          // eslint-disable-next-line no-unused-vars
          var shape = e.element ? elementRegistry.get(e.element.id) : e.shape
          if (event === 'shape.added') {
            console.log('新增了shape')
          } else if (event === 'shape.move.end') {
            console.log('移动了shape')
          } else if (event === 'shape.removed') {
            console.log('删除了shape')
          }
        })
      })
    },
    addEventBusListener() {
      // 监听 element
      const that = this
      const eventBus = this.bpmnModeler.get('eventBus')
      const eventTypes = ['element.click', 'element.changed']
      eventTypes.forEach(function(eventType) {
        eventBus.on(eventType, function(e) {
          if (!e || e.element.type === 'bpmn:Process') return
          if (eventType === 'element.changed') {
            that.elementChanged(eventType, e)
          } else if (eventType === 'element.click') {
            console.log('点击了element')
          }
        })
      })
    },
    elementChanged(eventType, e) {
      var shape = this.getShape(e.element.id)
      if (!shape) {
        // 若是shape为null则表示删除, 无论是shape还是connect删除都调用此处
        console.log('无效的shape')
        // 由于上面已经用 shape.removed 检测了shape的删除, 因此这里只判断是否是线
        if (this.isSequenceFlow(shape.type)) {
          console.log('删除了线')
        }
      }
      if (!this.isInvalid(shape.type)) {
        if (this.isSequenceFlow(shape.type)) {
          console.log('改变了线')
        }
      }
    },
    getShape(id) {
      var elementRegistry = this.bpmnModeler.get('elementRegistry')
      return elementRegistry.get(id)
    },
    isInvalid(param) { // 判断是否是无效的值
      return param === null || param === undefined || param === ''
    },
    isSequenceFlow(type) { // 判断是否是线
      return type === 'bpmn:SequenceFlow'
    }
  }
}
</script>

<style>
.containers {
  position: absolute;
  width: 105vh;
  height: 81vh;
}

.canvas {
  width: 105vh;
  height: 81vh;
}

#properties-panel {
  position: absolute;
  right: 0;
  top: 0;
  width: 300px;
}
</style>
